/*
 * $Log:: /Tornado/target/h/NB/rwos/rwcontainer.h                                                  $
 * 
 * 1     2/09/00 4:44p Admin
 * 
 * 1     8/27/99 1:00p Alex
 * 
 * 3     8/17/99 7:23p Rob
 * Created rw_container_free_items(), used to remove and free all items in a container. The items in
 * the container must be single-buffer items (single malloc) for this function to work without
 * leaking memory.
 * 
 * 2     7/01/99 3:39p Rajive
 * Made changes for CIDR tree.
 * 
 * 1     5/20/99 11:46a Alex
 * 
 * 1     4/14/99 5:10p Rajive
 * Initial vesrion of Next Gen RouterWare Source code
 * 
 * 1     1/18/99 5:10p Mahesh
 * 
 * 1     1/18/99 4:25p Mahesh
 * 
 * 5     11/13/98 9:20p Mahesh
 * 
 * 4     9/18/98 4:31p Mahesh
 * Changed C++ style comments to C style comments
 * 
 * 3     8/24/98 7:47p Mahesh
 * Added copyright notice.
 * 
 * 2     8/20/98 3:44p Mahesh
 * Changed iterator pointers to be JUST iterators.
 * 
 * 1     8/18/98 2:29p Mahesh
 * Initial Check In
 */
/************************************************************************/
/*	Copyright (C) 1998 RouterWare, Inc.	 								*/
/*	Unpublished - rights reserved under the Copyright Laws of the		*/
/*	United States.  Use, duplication, or disclosure by the 				*/
/*	Government is subject to restrictions as set forth in 				*/
/*	subparagraph (c)(1)(ii) of the Rights in Technical Data and 		*/
/*	Computer Software clause at 252.227-7013.							*/
/*	RouterWare, Inc., 3961 MacArthur Blvd. Suite 212, Newport Beach, CA	*/
/************************************************************************/
#if !defined RwContainer_h
#define RwContainer_h

typedef void RW_CONTAINER_ITEM;
typedef int (*FP_RW_CONTAINER_ITEM_COMPARE) (const RW_CONTAINER_ITEM* p_first_item, const RW_CONTAINER_ITEM* p_second_item);
	/*  returns 0 if the two items are equal, > 0 if first_item > second_item, and < 0 if otherwise. */

typedef void RW_CONTAINER_CRITERIA;
typedef bool (*FP_RW_CONTAINER_ITEM_CRITERIA_MATCHER) (const RW_CONTAINER_ITEM* p_item, RW_CONTAINER_CRITERIA* p_criteria);
	/* returns true if *itertor matches p_criteria */


/* class RW_CONTAINER:: */

typedef void RW_CONTAINER;
typedef int RW_CONTAINER_ITERATOR;

RW_EXPORT RW_CONTAINER_ITERATOR rw_container_create_iterator (RW_CONTAINER* p_rw_container);
RW_EXPORT void rw_container_free_iterator (RW_CONTAINER_ITERATOR iterator);

RW_EXPORT RW_CONTAINER_ITERATOR rw_container_create_copy_of_iterator (RW_CONTAINER_ITERATOR iterator);

RW_EXPORT void rw_container_free (RW_CONTAINER* p_rw_container);

RW_EXPORT void rw_container_free_items (RW_CONTAINER* p_rw_container);	/* Use only for single buffer items */

RW_EXPORT bool rw_container_add_front (RW_CONTAINER* p_rw_container, const RW_CONTAINER_ITEM* p_item);
RW_EXPORT void rw_container_remove_front (RW_CONTAINER* p_rw_container);
RW_EXPORT bool rw_container_add_back (RW_CONTAINER* p_rw_container, const RW_CONTAINER_ITEM* p_item);
RW_EXPORT void rw_container_remove_back (RW_CONTAINER* p_rw_container);
RW_EXPORT bool rw_container_insert (RW_CONTAINER_ITERATOR iterator, const RW_CONTAINER_ITEM* p_item);
RW_EXPORT bool rw_container_remove (RW_CONTAINER_ITERATOR iterator);

RW_EXPORT UINT rw_container_size (const RW_CONTAINER* p_rw_container);

RW_EXPORT RW_CONTAINER_ITEM* rw_container_front (const RW_CONTAINER* p_rw_container);
RW_EXPORT RW_CONTAINER_ITEM* rw_container_back (const RW_CONTAINER* p_rw_container);

RW_EXPORT bool rw_container_is_at_front (RW_CONTAINER_ITERATOR iterator);
RW_EXPORT bool rw_container_is_at_end (RW_CONTAINER_ITERATOR iterator);

RW_EXPORT void rw_container_goto_front (RW_CONTAINER_ITERATOR iterator);
RW_EXPORT void rw_container_goto_end (RW_CONTAINER_ITERATOR iterator);	/* end == last + 1 */

RW_EXPORT bool rw_container_find_by_content (RW_CONTAINER_ITEM* p_item,	RW_CONTAINER_ITERATOR iterator_matched_item);
RW_EXPORT bool rw_container_find (FP_RW_CONTAINER_ITEM_CRITERIA_MATCHER fp_criteria_matcher, RW_CONTAINER_CRITERIA* p_criteria,
						RW_CONTAINER_ITERATOR iterator_matched_item);
RW_EXPORT bool rw_container_find_in_range (RW_CONTAINER_ITERATOR iterator_first, RW_CONTAINER_ITERATOR iterator_last,
						FP_RW_CONTAINER_ITEM_CRITERIA_MATCHER fp_criteria_matcher, RW_CONTAINER_CRITERIA* p_criteria,
						RW_CONTAINER_ITERATOR iterator_matched_item);

RW_EXPORT bool rw_container_next (RW_CONTAINER_ITERATOR iterator);	/* return false if reaches the back. */
RW_EXPORT bool rw_container_previous (RW_CONTAINER_ITERATOR iterator);	/* return false if reaches the front */
RW_EXPORT RW_CONTAINER_ITEM* rw_container_at (RW_CONTAINER_ITERATOR iterator);
RW_EXPORT bool rw_container_set_at (RW_CONTAINER_ITERATOR iterator, const RW_CONTAINER_ITEM* p_item);


/* class RW_LIST:: */

RW_EXPORT RW_CONTAINER* rw_list_create (FP_RW_CONTAINER_ITEM_COMPARE fp_compare);
	/* If fp_compare == NULL, the list is unsorted. */


/* class RW_ARRAY:: */
RW_EXPORT RW_CONTAINER* rw_array_create (UINT max_number_of_items);

RW_EXPORT bool rw_array_offset (RW_CONTAINER_ITERATOR iterator, int offset);
RW_EXPORT int rw_array_difference (RW_CONTAINER_ITERATOR iterator_1, RW_CONTAINER_ITERATOR iterator_2);


/*  class RW_HASH_TABLE:: */

typedef void RW_HASH_KEY;
typedef UINT (*FP_RW_HASHER) (const RW_HASH_KEY* p_hash_key);
typedef UINT (*FP_RW_ITEM_HASHER) (const RW_CONTAINER_ITEM* p_item);

RW_EXPORT RW_CONTAINER* rw_hash_table_create (UINT max_hash_value, FP_RW_HASHER fp_hasher, FP_RW_ITEM_HASHER fp_item_hasher,
												 FP_RW_CONTAINER_ITEM_CRITERIA_MATCHER fp_rw_item_matcher);

RW_EXPORT bool rw_hash_table_find (const RW_HASH_KEY* p_hash_key, RW_CONTAINER_ITERATOR iterator_matched_item);
	/* hash table will use RW_HASH_KEY as match criteria during the search. */

/* class RW_MAP:: */

typedef void RW_MAP_KEY;
typedef int (*FP_RW_MAP_KEY_AND_ITEM_COMPARE) (const RW_MAP_KEY* p_map_key, const RW_CONTAINER_ITEM* p_item);

RW_EXPORT RW_CONTAINER* rw_map_create (FP_RW_MAP_KEY_AND_ITEM_COMPARE fp_map_key_and_item_compare, FP_RW_CONTAINER_ITEM_COMPARE fp_item_compare);

RW_EXPORT bool rw_map_find (const RW_MAP_KEY* p_map_key, RW_CONTAINER_ITERATOR iterator_matched_item);

/* class RW_CIDR_TREE: */

typedef struct RW_CIDR_KEY
{
	ULONG	key;
	ULONG mask_size_in_bits;
} RW_CIDR_KEY;

RW_EXPORT RW_CONTAINER* rw_cidr_tree_create (void);
RW_EXPORT bool rw_cidr_tree_insert (RW_CONTAINER* p_cidr_tree, const RW_CIDR_KEY* p_cidr_key, const RW_CONTAINER_ITEM* p_item);
RW_EXPORT bool rw_cidr_tree_find (const RW_CONTAINER* p_cidr_tree, const RW_CIDR_KEY* p_cidr_key, RW_CONTAINER_ITERATOR cidr_iterator);

RW_EXPORT bool rw_cidr_subtree_find (RW_CONTAINER_ITERATOR cidr_iterator, const RW_CIDR_KEY* p_cidr_key);

RW_EXPORT bool rw_cidr_tree_is_orphan (const RW_CONTAINER_ITERATOR cidr_iterator);

RW_EXPORT bool rw_cidr_tree_parent (RW_CONTAINER_ITERATOR cidr_iterator);

RW_EXPORT bool rw_cidr_tree_get_key (RW_CONTAINER_ITERATOR cidr_iterator, RW_CIDR_KEY* p_cidr_key);

#endif	/* RwContainer_h */
